package cn.itcast.user.util;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;
import java.security.Key;
import java.util.Date;

/**
 * `iss`: 该JWT的签发者
 * `sub`: 该JWT所面向的用户
 * `aud`: 接收该JWT的一方
 * `exp`(expires): 什么时候过期，这里是一个Unix时间戳
 * `iat`(issued at): 在什么时候签发的
 */
public class JwtUtil {
    public static String sercetKey = "gumeng";
    public final static long keeptime = 1000 * 60 * 60 * 60 * 24;
//    public final static long  keeptime=5000;//test

    /**
     *
     * @param id id
     * @param keepTime 毫秒
     * @return token
     */
    public static String generateToken(String id, long keepTime) {
        return generateToken(id, id, id, keepTime);
    }

    public static String generateToken(String id, String issuer, String subject, long keepTime) {
        long ttlMillis = keepTime;
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
        long nowMillis = System.currentTimeMillis();
        Date now = new Date(nowMillis);
        byte[] apiKeySecretBytes = DatatypeConverter.parseBase64Binary(sercetKey);
        Key signingKey = new SecretKeySpec(apiKeySecretBytes, signatureAlgorithm.getJcaName());

        JwtBuilder builder = Jwts.builder().setId(id)
                .setIssuedAt(now);
        if (subject != null) {
            builder.setSubject(subject);
        }
        if (issuer != null) {
            builder.setIssuer(issuer);
        }
        builder.signWith(signatureAlgorithm, signingKey);

        long expMillis = nowMillis + ttlMillis;
        Date exp = new Date(expMillis);
        builder.setExpiration(exp);
        return builder.compact();
    }

    public static String generateToken(String id, String issuer, String subject) {
        return generateToken(id, issuer, subject, keeptime);
    }

    public String updateToken(String token) {
        try {
            Claims claims = verifyToken(token);
            String id = claims.getId();
            String subject = claims.getSubject();
            String issuer = claims.getIssuer();
            Date date = claims.getExpiration();
            return generateToken(id, issuer, subject);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return "0";
    }

    public static Claims verifyToken(String token) {
        return Jwts.parser()
                .setSigningKey(DatatypeConverter.parseBase64Binary(sercetKey))
                .parseClaimsJws(token).getBody();
    }


}
